package com.example.sprintboot.controller;

import com.example.sprintboot.entity.User;
import com.example.sprintboot.security.UserDetailsImpl;
import com.example.sprintboot.service.UserService;
import com.example.sprintboot.util.JwtUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/auth")
public class AuthController {
    private final AuthenticationManager authenticationManager;
    private final JwtUtils jwtUtils;
    private final UserService userService;


    public AuthController(AuthenticationManager authenticationManager,
                          JwtUtils jwtUtils,
                          UserService userService) {
        this.authenticationManager = authenticationManager;
        this.jwtUtils = jwtUtils;
        this.userService = userService;
    }

    /**
     * 登录接口
     * @param loginRequest 包含用户名和密码的请求体
     * @return 包含JWT令牌和用户信息的响应
     */
    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        // 进行用户认证
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.username(),
                        loginRequest.password()
                )
        );

        // 设置认证信息到安全上下文
        SecurityContextHolder.getContext().setAuthentication(authentication);
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        User user = userDetails.getUser();

        // 生成JWT令牌和刷新令牌
        String accessToken = jwtUtils.generateToken(user.getUsername(), user.getUserId(), user.getRole());
        String refreshToken = jwtUtils.generateRefreshToken(user.getUsername(), user.getUserId(), user.getRole());

        // 构建响应数据
        Map<String, Object> response = new HashMap<>();
        response.put("token", accessToken);
        response.put("refreshToken", refreshToken);
        response.put("user", Map.of(
                "id", user.getUserId(),
                "username", user.getUsername(),
                "role", user.getRole().name(),
                "email", user.getEmail()
        ));

        return ResponseEntity.ok(response);
    }

    /**
     * 刷新令牌接口
     * @param refreshRequest 包含刷新令牌的请求体
     * @return 新的访问令牌
     */
    @PostMapping("/refresh")
    public ResponseEntity<?> refreshToken(@RequestBody RefreshRequest refreshRequest) {
        try {
            // 验证刷新令牌
            if (jwtUtils.validateToken(refreshRequest.refreshToken())) {
                // 从刷新令牌中获取用户信息
                String username = jwtUtils.getUsernameFromToken(refreshRequest.refreshToken());
                User user = userService.findByUsername(username);
                
                if (user != null) {
                    // 生成新的访问令牌
                    String newAccessToken = jwtUtils.generateToken(user.getUsername(), user.getUserId(), user.getRole());
                    
                    Map<String, Object> response = new HashMap<>();
                    response.put("token", newAccessToken);
                    return ResponseEntity.ok(response);
                }
            }
        } catch (Exception e) {
            // 刷新令牌无效
        }
        
        return ResponseEntity.status(401).body("刷新令牌无效");
    }

    /**
     * 注册接口
     * @param user 包含用户注册信息的请求体
     * @return 注册成功的用户信息
     */
    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody User user) {
        // 调用UserService进行用户注册
        User registeredUser = userService.register(user);

        // 注册成功后返回用户信息
        return ResponseEntity.ok(registeredUser);
    }

    /**
     * 登录请求数据传输对象
     */
    public record LoginRequest(String username, String password) {}

    /**
     * 刷新令牌请求数据传输对象
     */
    public record RefreshRequest(String refreshToken) {}
}